package com.itheima.utils;

import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.BatchStatus;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

/**
 * @see QiniuUtils
 */
public class QiniuUtils {
    //...生成上传凭证，然后准备上传
    private static String accessKey;
    private static String secretKey;
    private static String bucket;
    private static String zoo;

    //默认不指定key的情况下，以文件内容的hash值作为文件名
    private static String key = null;

    //构造一个带指定 Region 对象的配置类
    private static Configuration cfg;
    private static Auth auth;
    private static String upToken;

    static {
        InputStream resourceAsStream = QiniuUtils.class.getClassLoader().getResourceAsStream("Qiniu.properties");
        Properties properties = new Properties();
        try {
            properties.load(resourceAsStream);
            accessKey = properties.getProperty("accessKey");
            secretKey = properties.getProperty("secretKey");
            bucket = properties.getProperty("bucket");
            zoo = properties.getProperty("zoo");
            Region region = geRegionByZoo(zoo);
            cfg = new Configuration(region);
            auth = Auth.create(accessKey, secretKey);
            upToken = auth.uploadToken(bucket);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 通过配置文件中的zoo键,获得Region对象,其中使用反射
     *
     * @param zoo
     * @return
     */
    private static Region geRegionByZoo(String zoo) {
        Region region = null;
        try {
            Method method = Region.class.getMethod(zoo, null);
            region = (Region) method.invoke(null, null);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return region;
    }

    /**
     * @param accessKey
     * @see com.itheima.utils.QiniuUtils#setAccessKey
     */
    public static void setAccessKey(String accessKey) {
        QiniuUtils.accessKey = accessKey;
    }

    public static void setSecretKey(String secretKey) {
        QiniuUtils.secretKey = secretKey;
    }

    public static void setBucket(String bucket) {
        QiniuUtils.bucket = bucket;
    }

    /**
     * 不指定文件名字节数组的上传
     *
     * @param data 字节数组
     * @return
     */
    public static DefaultPutRet upload(byte[] data) {

        return upload(data, key);
    }

    /**
     * 指定文件名字节字节数组的上传
     *
     * @param data     字节数组
     * @param fileName 文件名
     * @return
     */
    public static DefaultPutRet upload(byte[] data, String fileName) {
        UploadManager uploadManager = new UploadManager(cfg);
        DefaultPutRet putRet = null;
        key = fileName;
        try {
            Response response = uploadManager.put(data, key, upToken);
            //解析上传成功的结果
            putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
            System.out.println(putRet.key);
            System.out.println(putRet.hash);
        } catch (QiniuException ex) {
            Response r = ex.response;
            System.out.println(r.toString());
            try {
                System.out.println(r.bodyString());
            } catch (QiniuException ex2) {
                //ignore
            }
        }
        return putRet;
    }

    /**
     * 删除文件
     *
     * @param fileName 被删除的文件名
     */
    public static void del(String fileName) {
        BucketManager bucketManager = new BucketManager(auth, cfg);
        key = fileName;
        try {
            bucketManager.delete(bucket, key);
        } catch (QiniuException ex) {
            //如果遇到异常，说明删除失败
            System.err.println(ex.code());
            System.err.println(ex.response.toString());
        }
    }

    /**
     * 批量删除功能，每次不得超过1000
     *
     * @param fileNames
     * @return
     */
    private static void delFilesLess1000(String[] fileNames) throws QiniuException {
        BucketManager bucketManager = new BucketManager(auth, cfg);
        BucketManager.BatchOperations batchOperations = new BucketManager.BatchOperations();
        batchOperations.addDeleteOp(bucket, fileNames);
        Response response = bucketManager.batch(batchOperations);
        BatchStatus[] batchStatusList = response.jsonToObject(BatchStatus[].class);
        for (int i = 0; i < fileNames.length; i++) {
            BatchStatus status = batchStatusList[i];
            String key = fileNames[i];
            System.out.print(key + "\t");
            if (status.code == 200) {
                System.out.println("delete success");
            } else {
                System.out.println(status.data.error);
            }
        }
    }

    public static void delFiles(String[] fileNames) throws QiniuException {
        int i = 0;
        while (i < fileNames.length-1000) {
            //得到1000个元素
            String[] temp = Arrays.copyOfRange(fileNames, i, i + 1000);
            delFilesLess1000(temp);
            i = i + 1000;
        }
        delFilesLess1000(Arrays.copyOfRange(fileNames,i,fileNames.length));
    }
}
